package pers.yaoliguo.bms.control.process;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import pers.yaoliguo.bms.control.BaseControl;
import pers.yaoliguo.bms.control.view.Message;
import pers.yaoliguo.bms.entity.SysUser;
import pers.yaoliguo.bms.entity.leaveBill;
import pers.yaoliguo.bms.service.ILeaveBillService;
import pers.yaoliguo.bms.uitl.PropertiesReader;

/**
 * @ClassName:       LeaveBillFlow
 * @Description:    TODO
 * @author:            yao
 * @date:            2017年8月20日        下午3:34:00
 */
@Controller
@RequestMapping("/LeaveBillFlowControl")
public class LeaveBillFlowControl extends BaseControl{
	
	@Resource
	ProcessEngine engine;
	
	@Autowired
	ILeaveBillService leaveBillService;
	
	@RequestMapping("/skipApprovaList")
	public String ApprovaList(){
		return "redirect:/views/approval/approvalList.html";
	}
	
	@ResponseBody
	@RequestMapping("/startProcess")
	public Object startProcess(String id){
		Message<leaveBill> msg = new Message<leaveBill>();
		SysUser user = getLoginUser();
		Map<String,Object> vue = new HashMap<String,Object>();
		vue.put("inputUser", user.getAccount());
		try {
			String leaveKey = PropertiesReader.getConfigValue("LeavaBill");
			String businesskey = leaveKey+"."+id;
			engine.getRuntimeService()//
			.startProcessInstanceByKey(leaveKey, businesskey, vue);
			leaveBill bill = new leaveBill();
			bill.setId(id);
			bill.setState(1);
			bill.setBusinesskey(businesskey);
			leaveBillService.updateByPrimaryKeySelective(bill);
			msg.setResult("200");
		} catch (Exception e) {
			msg.setResult("500");
		}
		return msg;
	}
	
	@ResponseBody
	@RequestMapping("/findByCurrentTask")
	public Object findByCurrentTask(){
		SysUser user = getLoginUser();
		Message<Map> msg = new Message<Map>();
		try {
			List<Task> list = engine.getTaskService()//
					.createTaskQuery()//
					.taskAssignee(user.getAccount())//
					.list();
			
			List<Map> resultList = new ArrayList<Map>();
			for (Task task : list) {
				TaskEntity te = (TaskEntity) task;
				Map map = new HashMap();
				map.put("taskId", te.getId());
				map.put("processInstanceId", te.getProcessInstanceId());
				//先查出
				ProcessInstance pi = engine.getRuntimeService().createProcessInstanceQuery()//
						.processInstanceId(te.getProcessInstanceId())//使用流程实例ID查询
						.singleResult();
				String buskey = pi.getBusinessKey();
				leaveBill bill = leaveBillService.selectByPrimaryKey(buskey.split("\\.")[1]);
				map.put("days", bill.getDays());
				map.put("content", bill.getContent());
				map.put("remark", bill.getRemark());
				map.put("leveDate", bill.getLeveDate());
				List listname = findOutgoingTransitions(te.getId());
				map.put("option", listname);
				resultList.add(map);
			}
			
			msg.setResult("200");
			msg.setDataList(resultList);
		} catch (Exception e) {
			e.printStackTrace();
			msg.setResult("500");
		}
		
		return msg;
	}
	
	//完成任务
	@ResponseBody
	@RequestMapping("/completeTask")
	public Object completeTask(String taskId,String message,String outcome){
		Message msg = new Message();
		try {
			TaskService ts = engine.getTaskService();
			Task tk = ts.createTaskQuery().taskId(taskId).singleResult();
			String processInstanceId = tk.getProcessInstanceId();
			//添加批注
			if(null == message){
				message = "";
			}
			
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("outcome", outcome);
			map.put("inputUser", "root");
			//先查出
			ProcessInstance pi = engine.getRuntimeService().createProcessInstanceQuery()//
					.processInstanceId(processInstanceId)//使用流程实例ID查询
					.singleResult();
			String buskey = pi.getBusinessKey();
			// 提交任务
			ts.complete(taskId, map);
			
			/**
			 * 5：在完成任务之后，判断流程是否结束
	   			如果流程结束了，更新请假单表的状态从1变成2（审核中-->审核完成）
			 */
			 pi = engine.getRuntimeService().createProcessInstanceQuery()//
					.processInstanceId(processInstanceId)//使用流程实例ID查询
					.singleResult();
			
			//流程结束了
			if(pi==null){
				//更新请假单表的状态从1变成2（审核中-->审核完成）
				leaveBill bill = new leaveBill();
				bill.setId(buskey.split("\\.")[1]);
				bill.setState(2);
				leaveBillService.updateByPrimaryKeySelective(bill);
			}
			msg.setResult("200");
		} catch (Exception e) {
			e.printStackTrace();
			msg.setResult("500");
		}
		return msg;
	}
	
	@RequestMapping("/viewImg")
	public void viewImg(HttpServletRequest request,HttpServletResponse response){
		String bk = request.getParameter("businesskey");
		ProcessInstance pi = engine.getRuntimeService().createProcessInstanceQuery().processInstanceBusinessKey(bk).singleResult();
		Task task =  engine.getTaskService().createTaskQuery().processInstanceId(pi.getId()).singleResult();
		//使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
		String InstanceId = task.getProcessInstanceId();
		List<Execution> executions = engine.getRuntimeService()//
								.createExecutionQuery()//
								.processInstanceId(InstanceId)//
								.list();
		RuntimeService runtimeService = engine.getRuntimeService();
		//得到正在执行的Activity的Id
        List<String> activityIds = new ArrayList<String>();
        List<String> flows = new ArrayList<String>();
        for (Execution exe : executions) {
            List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
            activityIds.addAll(ids);
        }
     
       //获取流程图
       BpmnModel bpmnModel = engine.getRepositoryService().getBpmnModel(pi.getProcessDefinitionId());
       ProcessEngineConfiguration engconf = engine.getProcessEngineConfiguration();
       ProcessDiagramGenerator diagramGenerator =  engconf.getProcessDiagramGenerator();
       InputStream in = diagramGenerator.generateDiagram(bpmnModel,"png",activityIds,flows,engconf.getActivityFontName(),engconf.getLabelFontName(),engconf.getClassLoader(),1);
       
       OutputStream out = null;
	   byte [] buf = new byte[1024];
	   int legth = 0;
		try {
			out = response.getOutputStream();
			while ((legth = in.read(buf)) != 0) {
					out.write(buf,0,legth);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(in != null){
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(out != null){
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public List<String> findOutgoingTransitions(String taskId){
		
		
		Task task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		//获取流程定义ID
		String processDefinitionId = task.getProcessDefinitionId();
		
		ProcessDefinitionEntity pd = (ProcessDefinitionEntity) engine.getRepositoryService()//
																		.getProcessDefinition(processDefinitionId);
		
		//使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
		String InstanceId = task.getProcessInstanceId();
		
		ProcessInstance pi = engine.getRuntimeService()//
										.createProcessInstanceQuery()//
										.processInstanceId(InstanceId)//
										.singleResult();
		//获取当前的活动
		ActivityImpl activityImpl = pd.findActivity(pi.getActivityId());
		List<String> list = new ArrayList<String>();
		//获取当前活动完成之后连线的名称
		List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();
		if(pvmList!=null && pvmList.size()>0){
			for(PvmTransition pvm:pvmList){
				String name = (String) pvm.getProperty("name");
				list.add(name);
			}
		}
		
		return list;
		
		
	}
	
}
